在經過多天的開發後,今天,我們的 行程管家 終於要邁入一個全新的階段──景點推薦系統的 UI 介面與基礎功能正式登場!
從這一刻起,行程管家不再只是靜靜待命的系統,而是一位能主動推薦、陪你探索的「旅程夥伴」。
讓我們讓它「真正上班」吧 。
介面設計:簡潔又不失溫度的旅遊推薦頁面
在這個頁面中,我們設計了一個結合 Spinner 下拉選單 與 ViewPager2 的互動式介面,
透過下拉選單,使用者可以輕鬆切換不同地區(例如:臺中、彰化、南投),
而下方的 ViewPager 則能夠依照地區自動切換對應的「推薦景點頁面」,
讓整體操作既直覺又具流暢感。
以下是我們設計好的 activity_places.xml程式碼
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.places.PlacesActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="600dp"
android:layout_gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:background="@color/GUNJYO"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="景點推薦"
android:gravity="center"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold" />
<Spinner
android:id="@+id/places_spinnerCategory_sp"
android:layout_width="match_parent"
android:layout_height="50dp"
android:padding="8dp" />
</LinearLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPagerPlaces"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
功能實作:下拉選單 × 分頁切換的巧妙互動
接下來,我們看看這個畫面的邏輯核心 —— PlacesActivity.java
它負責整合 Spinner 與 ViewPager2 的互動行為,
讓使用者在選擇地區時,畫面能自動切換對應的推薦內容頁面。
Placesactivity.java
package com.example.ittext.ui.places;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.example.ittext.R;
public class PlacesActivity extends AppCompatActivity {
private Spinner Placespinner;
private ViewPager2 viewPager;
private String[] count = {"臺中","彰化","南投"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_places);
Placespinner = findViewById(R.id.places_spinnerCategory_sp);
viewPager = findViewById(R.id.viewPager_Places_vp);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(this);
viewPager.setAdapter(viewPagerAdapter);
viewPager.setCurrentItem(0);
ArrayAdapter<CharSequence> spinnerAdapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item,count);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Placespinner.setAdapter(spinnerAdapter);
Placespinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) {
viewPager.setCurrentItem(position, true);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
// 當 ViewPager2 頁面改變時,同步更新 Spinner 的選擇
if (Placespinner.getSelectedItemPosition() == position) {
Placespinner.setSelection(position);
}
}
});
}
public static class ViewPagerAdapter extends FragmentStateAdapter {
public ViewPagerAdapter(FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@Override
@NonNull
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
default:
return null;
}
}
@Override
public int getItemCount() {
return 3;
}
}
}